﻿using _698._45Tool.Utils;
using CommonServiceLocator;
using Communication;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.CommandWpf;
using GalaSoft.MvvmLight.Ioc;
using GalaSoft.MvvmLight.Messaging;
using Jn698._45GWTool.Communication;
using Jn698._45GWTool.Services;
using Jn698._45GWTool.Settings;
using Jn698._45GWTool.ViewModels.Controls;
using Jn698._45GWTool.Views;
using nblTool.utils;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using WebFirst.Entities;
using WindowsFormsApp1.Utils;
using IOC = GalaSoft.MvvmLight.Ioc.SimpleIoc;

namespace Jn698._45GWTool.ViewModels
{
    public class ReadRecordViewModel:ViewModelBase
    {
        private EditRecordListService recordListService = new EditRecordListService();
        private SerialPortHelper serialPortHelper = SerialPortHelper.Instance;
        private TcpHelper tcpHelper = TcpHelper.Instance;

        private ObservableCollection<int> recordNum;

        public ObservableCollection<int> RecordNum
        {
            get { return recordNum; }
            set { Set(ref recordNum, value); }
        }
        private int selectedRecord;

        public int SelectedRecord
        {
            get { return selectedRecord; }
            set { Set(ref selectedRecord, value); UpdateRecordList(value + 1); }
        }
        private ObservableCollection<EditRecordList> recordDataList;

        public ObservableCollection<EditRecordList> RecordDataList
        {
            get { return recordDataList; }
            set { Set(ref recordDataList, value); }
        }

        private bool satae = true;

        public bool State
        {
            get { return satae; }
            set { Set(ref satae, value); }
        }

        private bool isCheck;

        public bool IsCheck
        {
            get { return isCheck; }
            set { Set(ref isCheck,value); }
        }

        /// <summary>
        /// cotr
        /// </summary>
        public ReadRecordViewModel()
        {
            RecordNum = new ObservableCollection<int>() { 1, 2, 3, 4, 5 };
            RecordDataList = new ObservableCollection<EditRecordList>();
            UpdateRecordList(1);
        }

        private void UpdateRecordList(int total)
        {
            RecordDataList.Clear();
            recordListService.Select(total).ForEach(t => RecordDataList.Add(t));
        }

        public override void Cleanup()
        {
            base.Cleanup();
            SimpleIoc.Default.Unregister<EditRecordList>();
            SimpleIoc.Default.Unregister<RecordChoiceViewModel>();
            SimpleIoc.Default.Unregister<RSDViewModel>();

        }

        public RelayCommand<int> MouseDoubleClickCommand
        {
            get
            {
                var command = new RelayCommand<int>((index) =>
                {
                    if (index < 0)
                    {
                        return;
                    }
                    Cleanup();
                    IOC.Default.Register(() => RecordDataList[index]);
                    IOC.Default.Register<RecordChoiceViewModel>();
                    IOC.Default.Register<RSDViewModel>();
                    RecordChoiceView recordChoiceView = new RecordChoiceView();
                    if (recordChoiceView.ShowDialog() == true)
                    {

                        //RecordDataList[index].StrRSD = RecordChoiceViewModel.EditRecord.StrRSD;
                        //RecordDataList[index].StrOAD = RecordChoiceViewModel.EditRecord.StrOAD;
                        //RecordDataList[index].StrRCSD = RecordChoiceViewModel.EditRecord.StrRCSD;
                        //UpdateRecordList(SelectedRecord+1);
                        /*gWCmdMakeUpService.Update(ModeBitViewModel.GWCmdMakeUp);
                        SetDataList[index].DataValue = ModeBitViewModel.GWCmdMakeUp.DataValue;*/
                    }
                });
                return command;
            }
        }

        public RelayCommand<int> SendCommand
        {
            get
            {
                var command = new RelayCommand<int>(async (index) =>
                {
                    if (MainViewModel.selectedDevice == null)
                    {
                        MessageBox.Show("请选择设备");
                        return;
                    }
                    if (index<0)
                    {
                        index = 0;
                    }
                    SendModule.SecuritySelectedIndex = ServiceLocator.Current.GetInstance<MainViewModel>().SecuritySelectedIndex;
                    switch (SendModule.SecuritySelectedIndex)
                    {

                        //明文+RN_MAC
                        case 2:
                        //明文+SID_MAC
                        case 3:
                        //密文+SID
                        case 4:
                        //密文+SID_MAC
                        case 5:
                            if (string.IsNullOrWhiteSpace(SendModule.SessionInitKey))
                            {
                                MessageBox.Show("请先建立应用连接");
                                return;
                            }
                            break;
                        //明文
                        case 0:
                        //明文+RN
                        case 1:
                        default:

                            break;
                    }
                    
                    
                    string frame = "";
                    string UserData = "";
                    byte[] byteAddress = StringUtils.strToHexByte(MainViewModel.selectedDevice.DeviceAddress);
                    List<byte> APDU;
                    if (IsCheck|| RecordDataList.Count==1)
                    {
                        if (index >= RecordDataList.Count)
                        {
                            return;
                        }
                        var recordData = RecordDataList[index];
                        UserData = "050300" + recordData.StrOAD + recordData.StrRSD + recordData.StrRCSD;
                    }
                    else
                    {
                        UserData = "050400"+ RecordDataList.Count.ToString("X2");
                        UserData += string.Join(",", RecordDataList.Select(item => item.StrOAD + item.StrRSD + item.StrRCSD)).Replace(",","");
                    }
                    if (TerminalSettings.Instanse.TimeTagFlag)
                    {
                        UserData += "01";
                        UserData += StringUtils.DateTime2String(DateTime.Now);
                        UserData += TerminalSettings.Instanse.TimeTagData;
                        
                    }
                    else
                    {
                        UserData += "00";
                    }
                    APDU = MessageGenerationModule.GetSecuriityFrame(StringUtils.hexStringToBytes(UserData.Replace(" ", string.Empty)).ToList(), SendModule.SecuritySelectedIndex);
                    //定义临时字节列表
                    List<byte> temp = new List<byte>();

                    temp.Add(0x68);
                    //长度域
                    short length = (short)(2 + 1 + 1 + (short)byteAddress.Length + 1 + 2 + (short)APDU.Count + 2);
                    //FrameLen = string.Format("{0:X2}{1:X2}", length & 0x00ff, length >> 8);
                    byte[] byteLength = BitConverter.GetBytes(length);

                    temp.AddRange(byteLength);

                    //控制域

                    //byte control = StringUtils.string_2_BCD(Control)[0];
                    temp.Add(0x43);

                    //地址域
                    //服务器地址SA
                    byte addressLen = (byte)(byteAddress.Length - 1);
                    if (MainViewModel.selectedDevice.DeviceAddress.Contains("A") || MainViewModel.selectedDevice.DeviceAddress.Contains("a"))
                    {
                        addressLen |= 0x40;
                    }
                    switch (TerminalSettings.Instanse.LogicAddressSelected)
                    {
                        case 1:
                            addressLen |= 0x10;
                            break;
                        case 2:
                            addressLen |= 0x20;
                            break;
                        case 3:
                            addressLen |= 0x30;
                            break;
                        case 0:
                        default:
                            break;
                    }
                    //temp.Add((byte)(byteAddress.Length - 1));
                    temp.Add(addressLen);
                    Array.Reverse(byteAddress);
                    temp.AddRange(byteAddress);

                    //客户机地址CA
                    byte ca = 0x11;
                    temp.Add(ca);

                    //帧头校验HCS
                    //HCS = ByteUtils.bytesToHexString(CheckSum.CRC16(temp, 1));
                    temp.AddRange(CheckSum.CRC16(temp, 1));

                    //链路用户数据
                    temp.AddRange(APDU);

                    //帧校验FCS
                    //FCS = ByteUtils.bytesToHexString(CheckSum.CRC16(temp, 1));
                    temp.AddRange(CheckSum.CRC16(temp, 1));

                    //结束字符
                    temp.Add(0x16);
                    frame = ByteUtils.bytesToHexString(temp);
                    
                    State = false;
                    byte[] b = StringUtils.hexStringToBytes(frame);
                    string msgStr = "";
                    for (int i = 0; i < b.Length; i++)
                    {
                        msgStr += b[i].ToString("X2") + " ";
                    }
                    Messenger.Default.Send<string>($"发送帧({DateTime.Now.ToString()})：{msgStr}", "SendMessage");
                    switch (CommViewModel.selectedCommType)
                    {
                        case "串口":
                            serialPortHelper.SendDataMethod(b);
                            await Task.Run(() => serialPortHelper.DataReceiveFunction());
                            break;
                        case "GPRS":
                            tcpHelper.SendData(MainViewModel.selectedDevice.DeviceAddress, b);
                            break;
                        default:
                            break;
                    }
/*                    serialPortHelper.SendDataMethod(b);
                    bool result = false;
                    await Task.Run(() => result = serialPortHelper.DataReceiveFunction());*/
                    State = true;
                });
                return command;
            }
        }
    }
}
